import { useState, useCallback } from 'react';
import { useErrorHandler } from './useErrorHandler';

interface ApiState<T> {
  data: T | null;
  loading: boolean;
  error: string | null;
}

interface UseApiStateOptions {
  initialData?: any;
  showErrorMessage?: boolean;
  errorMessage?: string;
}

export const useApiState = <T>(options: UseApiStateOptions = {}) => {
  const { initialData = null, showErrorMessage = true, errorMessage } = options;
  const { handleError } = useErrorHandler();
  
  const [state, setState] = useState<ApiState<T>>({
    data: initialData,
    loading: false,
    error: null,
  });

  const setLoading = useCallback((loading: boolean) => {
    setState(prev => ({ ...prev, loading }));
  }, []);

  const setData = useCallback((data: T) => {
    setState(prev => ({ ...prev, data, error: null }));
  }, []);

  const setError = useCallback((error: string) => {
    setState(prev => ({ ...prev, error, data: null }));
  }, []);

  const execute = useCallback(async <R>(
    apiCall: () => Promise<R>,
    options: {
      onSuccess?: (data: R) => void;
      onError?: (error: any) => void;
      transform?: (data: R) => T;
    } = {}
  ) => {
    const { onSuccess, onError, transform } = options;
    
    setLoading(true);
    setState(prev => ({ ...prev, error: null }));

    try {
      const result = await apiCall();
      const transformedData = transform ? transform(result) : (result as unknown as T);
      
      setData(transformedData);
      
      if (onSuccess) {
        onSuccess(result);
      }
      
      return result;
    } catch (error) {
      const errorMsg = error?.response?.data?.message || error?.message || '请求失败';
      setError(errorMsg);
      
      if (showErrorMessage) {
        handleError(error, { defaultMessage: errorMessage });
      }
      
      if (onError) {
        onError(error);
      }
      
      throw error;
    } finally {
      setLoading(false);
    }
  }, [handleError, showErrorMessage, errorMessage, setLoading, setData, setError]);

  const reset = useCallback(() => {
    setState({
      data: initialData,
      loading: false,
      error: null,
    });
  }, [initialData]);

  return {
    ...state,
    execute,
    reset,
    setLoading,
    setData,
    setError,
  };
};
